import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.util.ArrayList;
/**
 * Essa Classe Representa o Tabuleiro do Jogo.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Tabuleiro extends World
{
    private List TV1,TV2;
    private GreenfootSound tema;
    private int mundoAtual = 0;
    /**
     * O construtor dessa classe não recebe parametros e apenas prepara os objetos das outras classes,faz o sorteio das posições de cada e prepara a musica tema do jogo. 
     * 
     */
    public Tabuleiro()
    {    
        super(8, 8, 60); 
        Ladrao ladrao = new Ladrao();
        addObject(ladrao, 7,7);
        Placar p = new Placar(ladrao);
        addObject(p,4,4);
        ladrao.atualizarX();
        ladrao.atualizarY();
        
        gerarMundo();
        TV1 = removerMundo();
        removerTabuleiroAtual(TV1);
        
        gerarMundo();
        TV2 = removerMundo();
        removerTabuleiroAtual(TV2);
        
        /*
         *nesse construtor o primeiro parametro é a largura(em células)
         * o segundo parâmetro é a altura(ou é o contrário)
         * e o terceiro é o tamanho da célula.
        */
        tema = new GreenfootSound("tema.mp3");
        recolocarMundo(TV1);
        mundoAtual = 1;
    }
    
    private List removerMundo(){
        return getObjects(Personagem.class);
    }
    
    private void gerarMundo(){
        
        //Policia pulissa = new Policia();
        
        //addObject(pulissa, 0, 0);
        //criarCachorro();
        criarBarricada();
        criarDiamante();
        Bueiro bueiro1 = new Bueiro();
        adicionarBueiro(bueiro1);
        Bueiro bueiro2 = new Bueiro();
        adicionarBueiro(bueiro2);
        Bueiro bueiro3 = new Bueiro();
        adicionarBueiro(bueiro3);
        Bueiro bueiro4 = new Bueiro();
        adicionarBueiro(bueiro4);
        
        
        setarCoordenadaDestinoBueiro(bueiro1,bueiro2);
        setarCoordenadaDestinoBueiro(bueiro3,bueiro4);
        
        //pulissa.atualizarX();
        //pulissa.atualizarY();
        bueiro1.atualizarX();
        bueiro1.atualizarY();
        bueiro2.atualizarX();
        bueiro2.atualizarY();
        bueiro3.atualizarX();
        bueiro3.atualizarY();
        bueiro4.atualizarX();
        bueiro4.atualizarY();
    
    }
    
    public void mudarDeMundo(int sentido){
        List lista = getObjects(Ladrao.class);//tirando apenas o ladrao do tabuleiro
        Ladrao l = (Ladrao) lista.get(0);
        
        if(mundoAtual == 1){//checando onde ele está
            TV1 = removerMundo();
            removerTabuleiroAtual(TV1);
            recolocarMundo(TV2);//para onde esta indo,no caso só ha 2 mundos então
            mundoAtual = 2;     //ainda não se faz necessario checar para onde.
        }else{
            TV2 = removerMundo();
            removerTabuleiroAtual(TV2);
            recolocarMundo(TV1);
            mundoAtual = 1;
        }
        
        reposicionarLadrao(l,sentido);
    }
    
    private void reposicionarLadrao(Ladrao l, int sentido){
        int x,y;
        y = l.pegarY();
        
       if(sentido == 2){//Indo para a direita
           x = 0;//primeira posicao???
       }else{//indo para esquerda.
           x = 7;//ultima posicao???
       } 
       
       if(!checaPosicaoVazia(x, y)){//Não sei oq fazer quando a posicao não tá vazia D:
            do{
                y++;
            
            }while(!checaPosicaoVazia(x,y));
            
       }
        
        addObject(l, x, y);
        l.atualizarX();
        l.atualizarY();
    }
    
    private void recolocarMundo(List mundo){
        Personagem ator;
        int i = 0;
        
        do{
            ator = (Personagem) mundo.get(i);
            
            addObject(ator, ator.pegarX(), ator.pegarY());
            i++;
        }while(i < mundo.size());
        
    }
    
    private void removerTabuleiroAtual(List tabuleiro){
        removeObjects(tabuleiro);
    }

    /**
     * Essa Função recebe duas variaveis que representam uma posicao no tabuleiro e retorna true se essa posição está vaga ou false se ela já foi ocupada.
     */
     public Boolean checaPosicaoVazia(int x, int y){
           
         List teste = getObjectsAt(x, y, Actor.class);
        
         if(teste.isEmpty()){
            return true;
         }else{
            return false;   
         }
    }
 
    /**
     * Essa função cria os cachorros do jogo, passando o cachorro criado para o tabuleiro.
     */
    public void criarCachorro(){
         int x,y,quantidadeCachorro=0;
         Obstaculo arm;
         
                 do{
                    arm = new Cachorro();
                     if(adicionarObstaculo(arm)){
                        quantidadeCachorro++;   
                        arm.atualizarX();
                        arm.atualizarY();
                     }
                }while(quantidadeCachorro!= 3);
           
    }
    
    /**
     * Essa função é análoga a função de criar cachorros,só que cria as barricadasPoliciais.
     */      
    public void criarBarricada(){
         int x,y,quantidadeBarricada=0;
         Obstaculo arm;
         
                 do{
                    arm = new Barricada();
                    if(adicionarObstaculo(arm)){
                        quantidadeBarricada++;
                        arm.atualizarX();
                        arm.atualizarY();
                    }
                }while(quantidadeBarricada!= 15);
           
       }
       
     /**
      * Essa função recebe um Obstáculo e sortea uma posição aleatória do tabuleiro para inserir o Obstáculo informado.
      */
    private Boolean adicionarObstaculo(Obstaculo arm){
            int x, y;
            x = Greenfoot.getRandomNumber(getWidth()-1);
    
            y = Greenfoot.getRandomNumber(getHeight()-1);
            
          if(checaPosicaoVazia(x,y)){
            addObject(arm, x, y);
            return true;
            }
            return false;
    }
    
    /**
     * Método que cria um diamante.
     */
    public void criarDiamante(){
         int x,y,quantidadeDiamante=0;
         Diamante novoDiamante;
         
                 do{
                    novoDiamante = new Diamante();
                    if(adicionarDiamante(novoDiamante)){
                        quantidadeDiamante++;
                        novoDiamante.atualizarX();
                        novoDiamante.atualizarY();
                    }
                }while(quantidadeDiamante!= 7);
           
       }
    
    /**
     * Método que adiciona um diamante no tabuleiro.
     */
      public boolean adicionarDiamante(Diamante d){
        boolean teste = false;
        int x, y;
        do{        
            x = Greenfoot.getRandomNumber(getWidth());
            y = Greenfoot.getRandomNumber(getHeight());
            if(checaPosicaoVazia(x,y)){
                addObject(d, x, y);
                teste=true;
            }            
        }while(teste != true);
        return teste;
        
    }
    
    /**
     * Método que adiciona um bueiro no tabuleiro.
     */
    public void adicionarBueiro(Bueiro b){
        boolean teste = false;
        int x, y;
        do{        
            x = Greenfoot.getRandomNumber(getWidth());
            y = Greenfoot.getRandomNumber(getHeight());
            if(checaPosicaoVazia(x,y)){
                addObject(b, x, y);
                teste=true;
            }            
        }while(teste != true);
        
    }
    
    
    /**
     * Método que seta uma coordenada de destino para o bueiro.
     */
    public void setarCoordenadaDestinoBueiro(Bueiro b1,Bueiro b2){
        b1.setarDestino(b2.getX(), b2.getY());
        b2.setarDestino(b1.getX(), b1.getY());
    
    }
    
    
    /**
     * Essa função sobrescreve o metodo Started do tabuleiro,apenas pra iniciar a  musica do jogo.
     */
    public void started(){
        tema.playLoop();
    }
    
    /**
     * Essa função sobrescreve o stopped do world e só para a musica.
     */
    public void stopped(){
        tema.pause();
    }
}
